"use strict";
//简介
// 1. 装饰器本质是⼀种特殊的函数，它可以对：类、属性、⽅法、参数进⾏扩展，同时能让代码更简洁。
// 2. 装饰器⾃ 2015 年在 ECMAScript-6 中被提出到现在，已将近10年。
// 3. 截⽌⽬前，装饰器依然是实验性特性 ，需要开发者⼿动调整配置，来开启装饰器⽀持。
// 4. 装饰器有 5 种：
// 类装饰器
// 属性装饰器
// ⽅法装饰器
// 访问器装饰器
// 参数装饰器
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
// 备注：虽然 TypeScript5.0 中可以直接使⽤ 类装饰器 ，但为了确保其他装饰器可⽤，现阶段使⽤时，仍建议使⽤
// experimentalDecorators 配置来开启装饰器⽀持，⽽且不排除在来的版本中，官⽅会进⼀步调整装饰器的相关语法！
//类装饰器
//1. 基本语法
//类装饰器是⼀个应⽤在类声明上的函数，可以为类添加额外的功能，或添加额外的逻辑。
//基本语法
//类装饰器
//  Demo函数会在Person类定义时执⾏
//  参数说明：
//  ○ target参数是被装饰的类，即：Person
function Demo(target) {
    // console.log(target.prototype)
    target.prototype.xw = 19;
    target.prototype.toString = function () {
        // console.log(this)
        return JSON.stringify(this);
    };
    // 封闭其原型对象，禁⽌随意操作其原型对象
    // Object.seal(target.prototype)
}
//类
let Person12 = class Person12 {
    constructor(name, age) {
        this.name = name;
        this.age = age;
    }
};
Person12 = __decorate([
    Demo
], Person12);
//简写
// class Person2 {
//     constructor(public name: string, public age: number) {
//     }
// }
const p13 = new Person12('漳卅', 18);
// console.log(JSON.stringify(p12))
//应⽤举例
// 需求：定义⼀个装饰器，实现 Person 实例调⽤ toString 时返回 JSON.stringify 的执⾏结果。
console.log(p13.toString());
// interface Person12 {
//     x: number
// }
//@ts-ignore
Person12.prototype.x = 99;
//@ts-ignore
// console.log(p12.x)
//关于返回值
// 类装饰器有返回值：若类装饰器返回⼀个新的类，那这个新类将替换掉被装饰的类。
// 类装饰器⽆返回值：若类装饰器⽆返回值或返回 undefined ，那被装饰的类不会被替换。
function Demo2(target) {
    return class {
        constructor(name, age) {
            this.name = name;
            this.age = age;
        }
        // 装饰器有返回值时，该返回值会替换掉被装饰的类
        test() {
            console.log(200);
            console.log(300);
            console.log(400);
        }
    };
}
let Person13 = class Person13 {
    constructor(name, age) {
        this.name = name;
        this.age = age;
    }
    test() {
        console.log(100);
    }
};
Person13 = __decorate([
    Demo2
], Person13);
// console.log(Person13)
const p14 = new Person13("123", 123);
function test(fn) {
}
class Person14 {
}
test(Person14);
class Person15 {
    constructor(age) {
        this.age = age;
    }
}
function test2(fn) {
}
// Person15.wife = "123"
// console.log(Person15.wife)
test2(Person15);
//泛型约束
function LogTime(target) {
    return class extends target {
        constructor(...args) {
            super(...args);
            this.createTime = new Date();
        }
        getTime() {
            return `该对象的创建时间为${this.createTime}`;
        }
    };
}
let Person16 = class Person16 {
    constructor(name, age) {
        this.name = name;
        this.age = age;
    }
    speack() {
        console.log('你好啊');
    }
};
Person16 = __decorate([
    LogTime
], Person16);
const p16 = new Person16('张三', 18);
//@ts-ignore
console.log(p16.getTime());
